import { ref, watch, onUnmounted } from 'vue';

/**
 * @description 一个Vue3组合式函数，实现数字的动态增长（Count-Up）效果。
 * @param {import('vue').Ref<number> | number} targetValue - 目标数字，可以是ref或普通数字。
 * @param {number} duration - 动画持续时间（毫秒）。
 * @returns {import('vue').Ref<string>} - 一个ref，其值是格式化后的、动态变化的数字字符串。
 */
export function useCountUp(targetValue, duration = 2000) {
    const animatedValue = ref(0);
    const displayValue = ref('0');
    let frameId = null;

    const formatNumber = (num) => {
        // 保留两位小数，并使用逗号作为千位分隔符
        return num.toLocaleString(undefined, {
            minimumFractionDigits: 0,
            maximumFractionDigits: 2,
        });
    };

    const animate = (start, end, duration) => {
        let startTime = null;

        const step = (timestamp) => {
            if (!startTime) startTime = timestamp;
            const progress = Math.min((timestamp - startTime) / duration, 1);
            const currentValue = start + progress * (end - start);
            animatedValue.value = currentValue;
            displayValue.value = formatNumber(currentValue);

            if (progress < 1) {
                frameId = requestAnimationFrame(step);
            } else {
                // 确保动画结束时显示精确的目标值
                displayValue.value = formatNumber(end);
            }
        };

        frameId = requestAnimationFrame(step);
    };

    const stopAnimation = () => {
        if (frameId) {
            cancelAnimationFrame(frameId);
            frameId = null;
        }
    };

    watch(
        () => (typeof targetValue === 'function' ? targetValue() : targetValue),
        (newVal, oldVal) => {
            stopAnimation();
            const start = animatedValue.value || 0;
            // 将newVal转换为数字，以防传入的是格式化的字符串
            const end = Number(newVal) || 0;
            animate(start, end, duration);
        },
        { immediate: true }
    );

    onUnmounted(() => {
        stopAnimation();
    });

    return displayValue;
} 